﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using ArgusLib.InteropServices;

namespace ArgusLib.FFmpeg.avcodec
{
	public class AVPacket : NativeWrapper<Interop.AVPacketNative>
	{
		IntPtr allocatedPtr;

		#region Constructors
		public AVPacket()
			: base()
		{
			Interop.AVPacketNative packet = new Interop.AVPacketNative();
			int size = Marshal.SizeOf(typeof(Interop.AVPacketNative));
			this.allocatedPtr = Marshal.AllocHGlobal(size);
			Marshal.StructureToPtr(packet, this.allocatedPtr, false);
			((INativeWrapper)this).Initialize(packet, this.allocatedPtr);
		}
		#endregion

		#region Methods
		protected override void DisposeCore()
		{
#if Log
			Log.IncrementLevel();
			if (this.allocatedPtr != this.Pointer)
			{
				Log.WriteLine("Invalid Pointer!");
				throw new Exception("Invalid Pointer!");
			}

			Log.WriteLine("Calling av_free_packet...");
			Interop.Functions.av_free_packet(this);
			Log.WriteLine("av_free_packet returned");

			Log.Write("Calling Marshal.FreeHGlobal...");
			Marshal.FreeHGlobal(this.Pointer);
			Log.WriteLine("Done");
			Log.DecrementLevel();
#else
			Interop.Functions.av_free_packet(this);
			Marshal.FreeHGlobal(this.Pointer);
#endif
		}
		#endregion

		#region Properties
		public byte[] Data
		{
			get
			{
#if Log
				Log.IncrementLevel();
				Log.Write("AVPacket.Data == null: ");
				Log.WriteLine(this.Structure.data == IntPtr.Zero);
				Log.Write("Ptr = ");
				Log.Write(this.Structure.data);
				Log.Write("; Size = ");
				Log.WriteLine(this.Structure.size);
				if (this.Structure.data == IntPtr.Zero)
				{
					Log.DecrementLevel();
					return null;
				}
					
				byte[] data = new byte[this.Structure.size];
				Log.Write("Copy native buffer to managed array...");
				Marshal.Copy(this.Structure.data, data, 0, this.Structure.size);
				Log.WriteLine(" Done");
				Log.DecrementLevel();
				return data;
#else
				if (this.Structure.data == IntPtr.Zero)
				{
					return null;
				}
					
				byte[] data = new byte[this.Structure.size];
				Marshal.Copy(this.Structure.data, data, 0, this.Structure.size);

				return data;
#endif
			}
		}
		#endregion
	}
}
